#include <string.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

#include "result.h"
#include "epoll.h"
#include <cutils/sockets.h>


#define LOG_TAG "mysrv_test"
//#include <android/log.h>
#include <log/log.h>

using namespace android::init;

#define SOCKET_NAME_TEST  "mysock"
static int s_fdListen = -1;

void handle_socket_fd()
{
        int ret = -1;
        int new_fd = -1;
        char cmd[256];

        if(s_fdListen > 0){
                new_fd = accept(s_fdListen, nullptr, nullptr);
                if (new_fd < 0) {
                        return;
                }
                bzero(cmd, sizeof(cmd));
                ret = recv(new_fd, cmd,  256, 0);
                if(ret < 0){
                        ALOGE("recv socket error : %s ", strerror(errno));
                        return;
                }
                cmd[ret] = '\0';
        }

        ALOGE("recv client cmd: %s \n",cmd);
        close(new_fd);

}

void setup_socket(Epoll* epoll)
{
        //s_fdListen = android_get_control_socket(SOCKET_NAME_TEST);
        s_fdListen = socket(AF_LOCAL, SOCK_STREAM, 0);
                if (s_fdListen < 0) {
                ALOGE("get control socket error, name :  %s", SOCKET_NAME_TEST);
                exit(-1);
        }
        std::string path = "/dev/socket/mysocket" ;
        unlink(path.c_str());

        struct sockaddr_un  addr;
        addr.sun_family = AF_LOCAL;
        strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
        bind(s_fdListen, (const struct sockaddr *)&addr, sizeof(addr));

        listen(s_fdListen, 4);

        if (auto result = epoll->RegisterHandler(s_fdListen, handle_socket_fd); !result) {
                ALOGE("epoll RegisterHandler error: %s", result.error().error_string.c_str());
                exit(1);
        }
}


int main(int argc, char *argv[])
{
        //初始化epoll
        Epoll epoll;
        if (auto result = epoll.Open(); !result) {
                ALOGE("epoll Open error: %s", result.error().error_string.c_str());
                exit(1);
        }

        setup_socket(&epoll);
        while(true){
                auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
                if (auto result = epoll.Wait(epoll_timeout); !result) {
                        ALOGE("epoll Wait error: %s", result.error().error_string.c_str());
                }
        }

        return 0;
}

